package jp.dodododo.reloadable.filter;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import jp.dodododo.reloadable.serialization.SerializedObject;
import jp.dodododo.reloadable.serialization.impl.SerializedObjectImpl;

public class SessionFilter implements Filter {

	public synchronized void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException,
			ServletException {
		try {
			deserializeSession((HttpServletRequest) req);
			chain.doFilter(req, res);
		} catch (IOException e) {
			e.printStackTrace();
			throw e;
		} catch (ServletException e) {
			e.printStackTrace();
			throw e;
		} catch (RuntimeException e) {
			e.printStackTrace();
			throw e;
		} catch (Error e) {
			e.printStackTrace();
			throw e;
		} finally {
			serializeSession((HttpServletRequest) req);
		}
	}

	protected void deserializeSession(HttpServletRequest request) {
		HttpSession session = request.getSession(false);
		if (session == null) {
			return;
		}
		@SuppressWarnings("unchecked")
		Enumeration<String> attributeNames = session.getAttributeNames();
		while (attributeNames.hasMoreElements()) {
			String name = attributeNames.nextElement();
			Object value = session.getAttribute(name);
			if (value instanceof SerializedObject == false) {
				continue;
			}
			SerializedObject object = (SerializedObject) value;
			session.setAttribute(name, object.getObject());
		}
	}

	protected void serializeSession(HttpServletRequest request) {
		HttpSession session = request.getSession(false);
		if (session == null) {
			return;
		}
		@SuppressWarnings("unchecked")
		Enumeration<String> attributeNames = session.getAttributeNames();
		while (attributeNames.hasMoreElements()) {
			String name = attributeNames.nextElement();
			Object value = session.getAttribute(name);
			session.setAttribute(name, new SerializedObjectImpl(value));
		}
	}

	public void init(FilterConfig config) throws ServletException {
	}

	public void destroy() {
	}

}
